/*********************************************************************
 * std::future的一般用法总结：
 * 1、什么是future
 *    future是一种能够获取异步线程操作结果的手段，可以简单理解future是一种
 *    线程间同步的手段
 * 2、为什么需要future
 *     有时候为了获取异步线程的计算结果，需要写大量的回调函数，导致代码很凌乱，
 *     此时future就可以使用
 * 3、如何使用future
 *    见下述实现
 * ******************************************************************/
#include "common.h"
#include <iostream>
#include <string>
#include <vector>
#include <future>         // std::promise, std::future, std::async

int main()
{
	// 注意，如果不用一个变量f1保存返回的future,则默认构造的future会马上被销毁，销毁过程中会阻塞等待线程被执行完。
	std::future<std::string> f1 = std::async(std::launch::async, [](){ 
		    return std::string("hello, world");  // 创建线程， 设定 promise, 返回一个 future。区别于 std::launch::deferred（不会创建新的线程去执行该lambda函数，其实最好是使用 deferred 策略，否则可能出现内存问题，see link: https://svn.boost.org/trac/boost/ticket/12220）
		}); 

	std::vector< std::future<std::string> > vf;
	vf.push_back(std::move(f1));  // future不能够被复制，但是可以被move
	std::cout<<vf[0].get()<< std::endl; // get 方法阻塞，直到执行完成并返回结果，output: hello, world

	std::future<int> f2 = std::async(std::launch::async, [](){ 
		    cout<<8<<endl;
			return 8;
		}); 

	f2.wait(); //wait 方法等待执行完成，不返回结果

	std::future<int> future = std::async(std::launch::async, [](){ 
		    std::this_thread::sleep_for(std::chrono::seconds(3));
		    return 8;  
		}); 
 
    std::cout << "waiting...\n";
    std::future_status status;
    do {
        status = future.wait_for(std::chrono::seconds(1));
        if (status == std::future_status::deferred) {
            std::cout << "deferred\n";
        } else if (status == std::future_status::timeout) {
            std::cout << "timeout\n";
        } else if (status == std::future_status::ready) {
            std::cout << "ready!\n";
        }
    } while (status != std::future_status::ready); 
 
    std::cout << "result is " << future.get() << '\n';
}